/*******************************************************************************
 * Copyright (c) 2012 Alexandr Tsvetkov.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 *
 * Contributors:
 *     Alexandr Tsvetkov - initial API and implementation
 *
 * Project:
 *     TAO Library
 *
 * File name:
 *     DrawableManager.java
 *
 * License agreement:
 *
 * 1. This code is published AS IS. Author is not responsible for any damage that can be
 *    caused by any application that uses this code.
 * 2. Author does not give a garantee, that this code is error free.
 * 3. This code can be used in NON-COMMERCIAL applications AS IS without any special
 *    permission from author.
 * 4. This code can be modified without any special permission from author IF AND ONLY IF
 *    this license agreement will remain unchanged.
 * 5. SPECIAL PERMISSION for this code usage in COMMERCIAL application SHOULD be obtained
 *    from author.
 ******************************************************************************/
package ua.at.tsvetkov.images;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import ua.at.tsvetkov.util.Log;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

public class DrawableManager {

	/**
	 * Получает Drawable по ссылке.
	 * 
	 * @param urlString адрес для загрузки из интернета.
	 * @return Drawable или null
	 */
	public static Drawable loadDrawable(String urlString) {
		try {
			InputStream is = getInputStream(urlString);
			Drawable drawable = Drawable.createFromStream(is, "src");
			return drawable;
		} catch (Exception e) {
			Log.e(e);
			return null;
		}
	}

	/**
	 * Получает кешированный Drawable по ссылке.
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета.
	 * @param сacheFile файл для кеширования.
	 * @return Drawable или null
	 */
	public static Drawable loadCachedDrawable(Context context, String urlString, String сacheFile) {
		Bitmap bitmap = BitmapManager.getCachedBitmap(urlString, сacheFile);
		return new BitmapDrawable(context.getResources(), bitmap);
	}

	/**
	 * Получает кешированный Drawable по ссылке подгоняя по размеру.
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета.
	 * @param сacheFile файл для кеширования.
	 * @param width 
	 * @param height 
	 * @return Drawable или null
	 */
	public static Drawable loadCachedDrawableResized(Context context, String urlString, String сacheFile, int width, int height) {
		Bitmap bitmap = BitmapManager.getCachedBitmapResized(urlString, сacheFile, width, height);
		return new BitmapDrawable(context.getResources(), bitmap);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и встраивает в указанное ImageView
	 * 
	 * @param urlString адрес для загрузки из интернета
	 * @param imageView
	 */
	public static void loadDrawableToImageView(String urlString, ImageView imageView) {
		loadCachedDrawableToImageView(null, urlString, null, imageView, null);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и встраивает в указанное ImageView
	 * 
	 * @param urlString адрес для загрузки из интернета
	 * @param imageView
	 * @param progress если не null то по окончанию загрузки делает невидимым данный progress
	 */
	public static void loadDrawableToImageView(String urlString, ImageView imageView, ProgressBar progress) {
		loadCachedDrawableToImageView(null, urlString, null, imageView, progress);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и встраивает в указанное ImageView
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета
	 * @param сacheFile файл для кеширования. Если равен null то кеширование не проводиться.
	 * @param imageView
	 * @param progress если не null то по окончанию загрузки делает невидимым данный progress
	 */
	public static void loadCachedDrawableToImageView(final Context context, final String urlString, final String сacheFile, final ImageView imageView) {
		loadCachedDrawableToImageView(context, urlString, сacheFile, imageView, null);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и встраивает в указанное ImageView
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета
	 * @param сacheFile файл для кеширования. Если равен null то кеширование не проводиться.
	 * @param imageView
	 * @param progress если не null то по окончанию загрузки делает невидимым данный progress
	 */
	public static void loadCachedDrawableToImageView(final Context context, final String urlString, final String сacheFile, final ImageView imageView, final ProgressBar progress) {
		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				Drawable drawable = (Drawable) message.obj;
				if(drawable == null)
					return;
				imageView.setImageDrawable(drawable);
				if (progress != null)
					progress.setVisibility(View.INVISIBLE);
				imageView.setVisibility(View.VISIBLE);
			}
		};

		Thread thread = new Thread() {
			@Override
			public void run() {
				Drawable drawable = null;
				if (сacheFile != null)
					drawable = loadCachedDrawable(context, urlString, сacheFile);
				else
					drawable = loadDrawable(urlString);
				Message message = handler.obtainMessage(1, drawable);
				handler.sendMessage(message);
			}
		};
		thread.start();
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и встраивает в указанное ImageView
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета
	 * @param сacheFile файл для кеширования. Если равен null то кеширование не проводиться.
	 * @param imageView
	 * @param progress если не null то по окончанию загрузки делает невидимым данный progress
	 */
	public static void loadCachedDrawableResizedToImageView(final Context context, final String urlString, final String сacheFile, final ImageView imageView, final ProgressBar progress, final int width, final int height) {
		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				Drawable drawable = (Drawable) message.obj;
				if(drawable == null)
					return;
				imageView.setImageDrawable(drawable);
				if (progress != null)
					progress.setVisibility(View.INVISIBLE);
				imageView.setVisibility(View.VISIBLE);
			}
		};

		Thread thread = new Thread() {
			@Override
			public void run() {
				Drawable drawable = null;
				if (сacheFile != null)
					drawable = loadCachedDrawableResized(context, urlString, сacheFile, width, height);
				else
					drawable = loadDrawable(urlString);
				Message message = handler.obtainMessage(1, drawable);
				handler.sendMessage(message);
			}
		};
		thread.start();
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и делает фоном в указанном View
	 * 
	 * @param urlString адрес для загрузки из интернета
	 * @param imageView
	 */
	public static void loadDrawableToBackground(String urlString, View view) {
		loadCachedDrawableToBackground(null, urlString, null, view, null);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и делает фоном в указанном View
	 * 
	 * @param urlString адрес для загрузки из интернета
	 * @param imageView
	 * @param progress если не null то по окончанию загрузки делает невидимым данный progress
	 */
	public static void loadDrawableToBackground(String urlString, View view, ProgressBar progress) {
		loadCachedDrawableToBackground(null, urlString, null, view, progress);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и делает фоном в указанном View
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета
	 * @param сacheFile файл для кеширования
	 * @param imageView
	 */
	public static void loadCachedDrawableToBackground(Context context, String urlString, String сacheFile, View view) {
		loadCachedDrawableToBackground(context, urlString, сacheFile, view, null);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и делает фоном в указанном View
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета
	 * @param сacheFile файл для кеширования
	 * @param imageView
	 * @param progress если не null то по окончанию загрузки делает невидимым данный progress
	 */
	public static void loadCachedDrawableToBackground(final Context context, final String urlString, final String сacheFile, final View view, final ProgressBar progress) {
		final Handler handler = new Handler() {

			@SuppressWarnings("deprecation")
			@SuppressLint("NewApi")
			@Override
			public void handleMessage(Message message) {
				Drawable drawable = (Drawable) message.obj;
				if(drawable == null)
					return;
				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
					view.setBackground(drawable);
				} else {
					view.setBackgroundDrawable(drawable);
				}
				if (progress != null)
					progress.setVisibility(View.INVISIBLE);
				view.setVisibility(View.VISIBLE);
			}
		};

		Thread thread = new Thread() {
			@Override
			public void run() {
				Drawable drawable = null;
				if (сacheFile != null)
					drawable = loadCachedDrawable(context, urlString, сacheFile);
				else
					drawable = loadDrawable(urlString);
				Message message = handler.obtainMessage(1, drawable);
				handler.sendMessage(message);
			}
		};
		thread.start();
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и делает фоном в указанном View
	 * 
	 * @param urlString адрес для загрузки из интернета
	 * @param imageView
	 */
	public static void loadCachedDrawableResizedToBackground(String urlString, View view, final int width, final int height) {
		loadCachedDrawableResizedToBackground(null, urlString, null, view, null, height, height);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и делает фоном в указанном View
	 * 
	 * @param urlString адрес для загрузки из интернета
	 * @param imageView
	 * @param progress если не null то по окончанию загрузки делает невидимым данный progress
	 */
	public static void loadCachedDrawableResizedToBackground(String urlString, View view, ProgressBar progress, final int width, final int height) {
		loadCachedDrawableResizedToBackground(null, urlString, null, view, progress, height, height);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и делает фоном в указанном View
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета
	 * @param сacheFile файл для кеширования
	 * @param imageView
	 */
	public static void loadCachedDrawableResizedToBackground(Context context, String urlString, String сacheFile, View view, final int width, final int height) {
		loadCachedDrawableResizedToBackground(context, urlString, сacheFile, view, null, height, height);
	}

	/**
	 * Получает кешированный Drawable по ссылке в потоке и делает фоном в указанном View
	 * 
	 * @param context
	 * @param urlString адрес для загрузки из интернета
	 * @param сacheFile файл для кеширования
	 * @param imageView
	 * @param progress если не null то по окончанию загрузки делает невидимым данный progress
	 */
	public static void loadCachedDrawableResizedToBackground(final Context context, final String urlString, final String сacheFile, final View view, final ProgressBar progress, final int width, final int height) {
		final Handler handler = new Handler() {

			@SuppressWarnings("deprecation")
			@SuppressLint("NewApi")
			@Override
			public void handleMessage(Message message) {
				Drawable drawable = (Drawable) message.obj;
				if(drawable == null)
					return;
				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
					view.setBackground(drawable);
				} else {
					view.setBackgroundDrawable(drawable);
				}
				if (progress != null)
					progress.setVisibility(View.INVISIBLE);
				view.setVisibility(View.VISIBLE);
			}
		};

		Thread thread = new Thread() {
			@Override
			public void run() {
				Drawable drawable = null;
				if (сacheFile != null)
					drawable = loadCachedDrawableResized(context, urlString, сacheFile, width, height);
				else
					drawable = loadDrawable(urlString);
				Message message = handler.obtainMessage(1, drawable);
				handler.sendMessage(message);
			}
		};
		thread.start();
	}

	private static InputStream getInputStream(String urlString) throws MalformedURLException, IOException {

		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpGet request = new HttpGet(urlString);
		HttpResponse response = httpClient.execute(request);
		return response.getEntity().getContent();
	}

}
